const Controller = require('egg').Controller;
//

// 开盘时间设置为 5min
const setTimeFive = 300000;
// 设置等待时间传给合约 5min
const setDelay = 300000;
// 获取合约里面的 balance
const balance = 101;

// 前端提交过来的数据要求 判断用
class ActionController extends Controller {

    /*
    * 传值有 limit offset where
    * 排序是按照 dateTime 下单时间来的
    * */
    async index() {
        const ctx = this.ctx;
        
        // 
        let limit = ctx.query.limit;
        let offset = (ctx.query.offset - 1) * ctx.query.limit;
        let order = 'dateTime';
        let userAddress_id = ctx.query.userAddress_id;
        let contract_id = ctx.query.contract_id;
        // service import
        ctx.body = await ctx.service.action.list(
            limit, offset * ctx.query.limit, order, userAddress_id, contract_id, ctx.query);
    }

    // 冻结余额 struct_id:  0 就是没传给合约的
    async blocked_balances() {
        const ctx = this.ctx;
        let userAddress_id = ctx.query.userAddress_id;
        let contract_id = ctx.query.contract_id;
        let struct_id = 0;
        ctx.status = 200;
        ctx.body = await ctx.service.action.blockedBalance(userAddress_id, contract_id, struct_id);

    }
    /**
     * 1、拿到冻结余额 + 提交的订到判断一下 + 
     * 2、随机数是否存在
     * 3、dateTime 本地时间  |  openTime = openTime - openTime % 300000
     * */
    async create() {
        const ctx = this.ctx;
        ctx.status = 201;
        ctx.body = await ctx.service.action.create(balance, setTimeFive);

    }
    /**
    * 提现
    * 1、validate 插入数据库要的字段
    * 2、validate 数据库 action_id 是否存在
    * 3、冻结有 hotel + actions + 当前提现的金额 是否超过余额 
    * */
    async hotel() {
        // 统计 action 表中冻结的金额
        const ctx = this.ctx;
        // 添加数据
        const res = await ctx.service.action.hotel(balance);
        // service 返回的错误信息
        if(res.status_code == 422) {
            ctx.status = 422;
            ctx.body = res;
            return;
        }

        // -----------------------------------------------------
        // 1、传数据给合约
        // 2、接受返回的值，然后删除还是提现成功
        // -----------------------------------------------------
        // 添加进数据库的那个随机数 res.action_id;

        const where = {
            where: {
                action_id:  res.action_id,
            }
        };
        // 这里按理只会有一条, 因为 action_id 唯一
        const rows = await ctx.model.Hotel.findAll(where);
        rows.forEach(async function (row) {
            const hotel = await ctx.model.Hotel.findById(row.id)
            // 提现成功
            await hotel.update({ struct_id:1 });
            // 提现失败
            // await hotel.destroy();
        });
        ctx.body = {'status_code':201, 'msg': '数据返回成功！'};

    }

    /**
    * 轮询自己是数据库，传给智能合约
    *
    * struct_id: 0 代表这个东西还没传过给智能合约，传过会给我返回值，我自然会改 struct_id: 改为 0
    * 1、数据库没有一条符合条件的轮询
    * 2、符合条件轮询了，但是指定 delay + dateTime 不符合条件发送到合约
    * */
    async send() {
        const ctx = this.ctx;
        //
        const query = {
            where: {
                struct_id: 0
            }
        };
        const actions = await ctx.model.Action.findAll(query);
        // 数据库没有一条符合条件的轮询，直接结束
        if (!actions) {
            ctx.body = {'status_code':404, 'msg': '没有单子要传！'};
            return;
        }
        // 循环
        actions.forEach(async function (row) {
            const myDate = Date.now();
            // 
            if(myDate >= parseInt(row.dateTime) + setDelay) {
                ctx.status = 200;
                const Action = await ctx.model.Action.findById(row.id);
                
                // 传给合约 根据返回值判断是否成功 res.action_id 合约返回的
                // -----------------------------------------------------
                // 1、传数据给合约 上面Action，下面 action_id 是返回的
                // 2、接受返回的值，然后删除还是提现成功
                // -----------------------------------------------------
                const where = {
                    where: {
                        action_id:  Action.action_id,
                    }
                };
                const rows = await ctx.model.Action.findAll(where);
                rows.forEach(async function (row) {
                    const action = await ctx.model.Action.findById(row.id)
                    // 下单成功
                    await action.update({ struct_id:1 });
                    // 下单失败
                    // await action.destroy();
                });
                
                // ctx.status = 204;
            }else {
                ctx.body = {'status_code':404, 'msg': '有单子但是时间没到'};
            }
        })
    }
}

module.exports = ActionController;